package com.ruoyi.file.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.config.properties.MinioProperties;
import com.ruoyi.common.enums.WhetherEnum;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.file.domain.FileInfo;
import com.ruoyi.file.domain.qo.FileInfoPageQo;
import com.ruoyi.file.domain.qo.FileInfoQo;
import com.ruoyi.file.domain.vo.FileInfoVo;
import com.ruoyi.file.mapper.FileInfoMapper;
import com.ruoyi.file.service.FileInfoService;
import io.minio.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;

/**
 * 文件信息表（存储Minio文件元数据信息）(FileInfo)表服务实现类
 *
 * @author admin
 * @since 2025-07-23 10:50:03
 */
@Slf4j
@Service("fileInfoService")
public class FileInfoServiceImpl extends ServiceImpl<FileInfoMapper, FileInfo> implements FileInfoService {

//    @Autowired
//    private MinioClient minioClient;
//    @Autowired
//    private MinioProperties minioProperties;

//
//    @Override
//    public FileInfo uploadFile(MultipartFile file, String businessType,String remark) throws Exception {
//        // 1. 检查存储桶是否存在，不存在则创建
//        createBucketIfNotExists();
//
//        // 2. 生成唯一文件名
//        String originalFilename = file.getOriginalFilename();
//        String extension = FilenameUtils.getExtension(originalFilename);
//        String objectName = generateObjectName(extension, businessType);
//        String fileMd5 = DigestUtils.md5Hex(file.getInputStream());
//        String fileCategory = determineFileCategory(originalFilename);
//
//        FileInfo myFileInfo = this.baseMapper.selectOne(new QueryWrapper<FileInfo>().eq("file_md5", fileMd5)
//                                                                                    .eq("del_tag", WhetherEnum.NO.getCode()));
//        if(myFileInfo != null){
//            return myFileInfo;
//        }
//
//        // 3. 上传文件到Minio
//        minioClient.putObject(
//                PutObjectArgs.builder()
//                        .bucket(minioProperties.getBucketName())
//                        .object(objectName)
//                        .stream(file.getInputStream(), file.getSize(), -1)
//                        .contentType(file.getContentType())
//                        .build());
//
//        // 4. 保存文件信息到数据库
//        FileInfo fileInfo = new FileInfo();
//        fileInfo.setFileName(originalFilename);
//        fileInfo.setFilePath(objectName);
////        fileInfo.setFileSize(file.getSize());
////        fileInfo.setFileType(file.getContentType());
////        fileInfo.setBucketName(minioProperties.getBucketName());
//        fileInfo.setBusinessType(businessType);
////        fileInfo.setFileMd5(fileMd5);
////        fileInfo.setFileCategory(fileCategory);
//        fileInfo.setRemark(remark);
////        fileInfo.setFileStatus(WhetherEnum.getEnum( true).getCode());
//        this.baseMapper.insert(fileInfo);
//
//        return fileInfo;
//    }


    @Override
    public FileInfo add(String code,String newFileName, String businessType, String remark, String url){
        FileInfo fileInfo = new FileInfo();
        fileInfo.setCode(code);
        fileInfo.setNewFileName(newFileName);
        fileInfo.setUrl(url);
        fileInfo.setBusinessType(businessType);
        fileInfo.setRemark(remark);
        this.baseMapper.insert(fileInfo);
        return fileInfo;
    }

    @Override
    public String importData(List<FileInfo> fileInfos, boolean updateSupport) {
        if (CollectionUtils.isEmpty(fileInfos))
        {
            throw new ServiceException("导入文件信息不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        for (FileInfo fileInfo : fileInfos){
            try
            {
                FileInfo myFileInfo = null;
                if(fileInfo.getId() !=null){
                    myFileInfo =this.baseMapper.selectById(fileInfo.getId());
                }
                if(myFileInfo == null && fileInfo.getId() == null) {
                    fileInfo.setDeptId(SecurityUtils.getDeptId());
                    this.save(fileInfo);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、文件名称 " + fileInfo.getNewFileName() + " 导入成功");
                }
                else if (updateSupport) {
                    this.updateById(fileInfo);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、文件名称 " + fileInfo.getNewFileName() + " 更新成功");
                }else {
                    failureNum++;
                    failureMsg.append("<br/>" + failureNum + "、文件名称 " + fileInfo.getNewFileName() + " 已存在");
                }
            }
            catch (Exception e) {

                failureNum++;
                String msg = "<br/>" + failureNum + "、文件名称 " + fileInfo.getNewFileName() + " 导入失败：";
                failureMsg.append(msg + e.getMessage());
            }
        }

        if (failureNum > 0)
        {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new ServiceException(failureMsg.toString());
        }
        else
        {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }

//    @Override
//    public InputStream downloadFile(FileInfo fileInfo) throws Exception {
//
//        return minioClient.getObject(
//                GetObjectArgs.builder()
//                        .bucket(fileInfo.getBucketName())
//                        .object(fileInfo.getFilePath())
//                        .build());
//
//    }


//    @Override
//    public GetObjectResponse downloadObject(FileInfo fileInfo) throws Exception {
//        return minioClient.getObject(
//                GetObjectArgs.builder()
//                        .bucket(fileInfo.getBucketName())
//                        .object(fileInfo.getFilePath())
//                        .build());
//    }

//    @Override
//    public IPage<FileInfo> pageFiles(FileInfoPageQo pageQo) {
//        LambdaQueryWrapper<FileInfo> queryWrapper =  getQueryWrapper(pageQo);
//        IPage<FileInfo> page = getPage(queryWrapper,pageQo.getPageNum() ==null? 1:pageQo.getPageNum(),pageQo.getPageSize() ==null?10:pageQo.getPageSize());
//        return page;
//    }

    @DataScope
    public IPage<FileInfo> getPage(LambdaQueryWrapper<FileInfo> queryWrapper,Integer pageNum, Integer pageSize){
        IPage<FileInfo> page = this.page(new Page<>(pageNum, pageSize), queryWrapper);
        return page;
    }

//    @Override
//    public void deleteFile(Long fileId) {
//        FileInfo fileInfo = this.baseMapper.selectById(fileId);
//        if(fileInfo == null){
//            log.error("删除文件：{} 对应的信息未找到", fileId);
//            throw new ServiceException("对应的文件信息未找到");
//        }
//        try {
//            minioClient.removeObject(RemoveObjectArgs.builder()
//                    .bucket(fileInfo.getBucketName())
//                    .object(fileInfo.getFilePath())
//                    .build());
//        } catch (Exception e) {
//            throw new ServiceException("删除文件失败,删除服务器上文件失败" );
//        }
//        this.baseMapper.deleteById(fileId);
//    }

//    @Transactional(propagation = Propagation.NESTED,rollbackFor = Exception.class)
//    @Override
//    public void deleteFiles(List<Long> fileIds) {
//        for (Long fileId : fileIds) {
//            deleteFile(fileId);
//        }
//    }


    public LambdaQueryWrapper<FileInfo> getQueryWrapper(FileInfoQo fileInfo) {
        LambdaQueryWrapper<FileInfo> queryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.hasText(fileInfo.getBusinessType())) {
            queryWrapper.eq(FileInfo::getBusinessType, fileInfo.getBusinessType());
        }
//        if(fileInfo.getFileStatus()!=null){
//            queryWrapper.eq(FileInfo::getFileStatus,WhetherEnum.getEnum(fileInfo.getFileStatus()).getCode());
//        }
        if(StringUtils.hasText(fileInfo.getCode())){
            queryWrapper.eq(FileInfo::getCode,fileInfo.getCode());
        }
        if(fileInfo.getCreateTimeStart()!=null ){
            queryWrapper.ge(FileInfo::getCreateTime,fileInfo.getCreateTimeStart());
        }
        if(fileInfo.getCreateTimeEnd()!=null ){
            // 将结束时间调整为当天的最后一秒
            java.time.LocalDateTime endOfDay = java.time.LocalDateTime.ofInstant(
                    fileInfo.getCreateTimeEnd().toInstant(),
                    java.time.ZoneId.systemDefault()
            ).with(java.time.LocalTime.MAX);
            queryWrapper.le(FileInfo::getCreateTime, java.util.Date.from(endOfDay.atZone(java.time.ZoneId.systemDefault()).toInstant()));

        }
        if (StringUtils.hasText(fileInfo.getKeyword())) {
            queryWrapper.like(FileInfo::getNewFileName, fileInfo.getKeyword()).or().like(FileInfo::getRemark, fileInfo.getKeyword()).or().like(FileInfo::getCode, fileInfo.getKeyword());
        }
        //queryWrapper.orderByAsc(FileInfo::getBusinessType);
        queryWrapper.orderByDesc(FileInfo::getId);
        return queryWrapper;
    }

//    @Transactional(propagation = Propagation.NESTED,rollbackFor = Exception.class)
//    @Override
//    public List<FileInfo> uploadFiles(MultipartFile[] files, String businessType ,String remark) throws Exception {
//        List<FileInfo> fileInfos = new ArrayList<>();
//        for (MultipartFile file : files) {
//            fileInfos.add(uploadFile(file, businessType,remark));
//        }
//        return fileInfos;
//    }

//    @Override
//    public List<FileInfo> getByIds(List<Long> fileIds) {
//        LambdaQueryWrapper<FileInfo> queryWrapper = new LambdaQueryWrapper<>();
//        queryWrapper.in(FileInfo::getId,fileIds);
//        return this.baseMapper.selectList(queryWrapper);
//    }

//    @Override
//    public FileInfoVo toVo(FileInfo fileInfo) {
//        FileInfoVo vo = new FileInfoVo();
//        BeanUtils.copyBeanProp(vo,fileInfo);
//        if(fileInfo.getFileStatus()!=null){
//            vo.setFileStatus(WhetherEnum.getEnum(fileInfo.getFileStatus()).isDefault());
//        }
//        return vo;
//    }
//
//    @Override
//    public FileInfo toEntity(FileInfoVo fileInfoVo) {
//        FileInfo fileInfo = new FileInfo();
//        BeanUtils.copyBeanProp(fileInfo,fileInfoVo);
//        if(fileInfoVo.getFileStatus()!=null) {
//            fileInfo.setFileStatus(WhetherEnum.getEnum(fileInfoVo.getFileStatus()).getCode());
//        }
//        return fileInfo;
//    }


//    private void createBucketIfNotExists() throws Exception {
//        boolean found = minioClient.bucketExists(BucketExistsArgs.builder()
//                .bucket(minioProperties.getBucketName())
//                .build());
//        if (!found) {
//            minioClient.makeBucket(MakeBucketArgs.builder()
//                    .bucket(minioProperties.getBucketName())
//                    .build());
//        }
//    }

//    private static String generateObjectName(String extension, String businessType) {
//        String uuid = UUID.randomUUID().toString();
//        if (businessType != null && !businessType.isEmpty()) {
//            return String.format("%s/%s.%s", businessType, uuid, extension);
//        }
//        return String.format("%s.%s", uuid, extension);
//    }


    /**
     * 根据文件名判断文件分类
     */
//    private String determineFileCategory(String filename) {
//        if (!StringUtils.hasText(filename)) {
//            return "other";
//        }
//
//        String extension = FilenameUtils.getExtension(filename).toLowerCase();
//
//        switch (extension) {
//            case "jpg":
//            case "jpeg":
//            case "png":
//            case "gif":
//            case "bmp":
//            case "webp":
//                return "image";
//
//            case "mp4":
//            case "avi":
//            case "mov":
//            case "wmv":
//            case "flv":
//                return "video";
//
//            case "pdf":
//            case "doc":
//            case "docx":
//            case "xls":
//            case "xlsx":
//            case "ppt":
//            case "pptx":
//                return "document";
//
//            case "zip":
//            case "rar":
//            case "7z":
//            case "tar":
//            case "gz":
//                return "archive";
//
//            default:
//                return "other";
//        }
//    }
}

